import numpy as np
def getXmostFilledRows(dataMatrix, nbrOfRowsToReturn):
	dataMatrixRet = dataMatrix
	nbrOfRows, numberOfColumns = np.shape(dataMatrixRet)
	countsAsRow = np.zeros(nbrOfRows).reshape((nbrOfRows,1))

	for i in range(nbrOfRows):	
		countsAsRow[i] = np.count_nonzero(dataMatrixRet[i,:])

	dataMatrixRet = np.hstack((dataMatrixRet, countsAsRow))
	dataMatrixRet = dataMatrixRet[dataMatrixRet[:,numberOfColumns].argsort()]
	dataMatrixRet = np.delete(dataMatrixRet, numberOfColumns, axis=1)

	if nbrOfRows < nbrOfRowsToReturn:
		return dataMatrixRet
	else:
		return dataMatrixRet[(nbrOfRows-nbrOfRowsToReturn):,:]

def getXmostFilledRowsByCol(dataMatrix, nbrOfRowsToReturn, columnsToCount):
	dataMatrixRet = dataMatrix
	nbrOfRows, numberOfColumns = np.shape(dataMatrixRet)
	countsAsRow = np.zeros(nbrOfRows).reshape((nbrOfRows,1))

	for i in range(nbrOfRows):	
		countsAsRow[i] = np.count_nonzero(dataMatrixRet[i,columnsToCount])

	dataMatrixRet = np.hstack((dataMatrixRet, countsAsRow))
	dataMatrixRet = dataMatrixRet[dataMatrixRet[:,numberOfColumns].argsort()]
	dataMatrixRet = np.delete(dataMatrixRet, numberOfColumns, axis=1)

	if nbrOfRows < nbrOfRowsToReturn:
		return dataMatrixRet
	else:
		return dataMatrixRet[(nbrOfRows-nbrOfRowsToReturn):,:]


def combineCategoricals(dataMatrix, columnsToCombine):
	dataMatrixRet = dataMatrix
	nbrOfRows, numberOfColumns = np.shape(dataMatrixRet)
	combinedRow = np.zeros(nbrOfRows).reshape((nbrOfRows,1))

	for i in range(nbrOfRows):
		sumOfColumns = 0
		for j in columnsToCombine:
			sumOfColumns += dataMatrixRet[i,j]
		
		if sumOfColumns < 1:	
				combinedRow[i] = 0
		else:
				combinedRow[i] = 1

	dataMatrixRet = np.hstack((dataMatrixRet, combinedRow))
	return dataMatrixRet

def getNumberOfDifferentValues(dataMatrix, attributeNamesSelected):
	#Calculate number of zeros and missing values in the continous attributes for selected data
	dataRows, dataColumns = np.shape(dataMatrix)
	numOfDifferentValues = np.zeros((dataColumns, 3)).astype(float)
	for i in xrange(0, dataColumns):
		numOfZeros = 0
		numOfmissingValues = 0
		numOfNotInUniverse = 0

		for j in xrange(0, dataRows):
			if dataMatrix[j,i].strip() == "0.0":
				numOfZeros = numOfZeros + 1
			if dataMatrix[j,i].find("Not in") != -1:
				numOfNotInUniverse = numOfNotInUniverse + 1
			if dataMatrix[j,i].find("United-States") != -1:
				numOfmissingValues = numOfmissingValues + 1
		
		numOfDifferentValues[i,0] = float(numOfZeros)/dataRows
		numOfDifferentValues[i,1] = float(numOfNotInUniverse)/dataRows
		numOfDifferentValues[i,2] = float(numOfmissingValues)/dataRows

	numOfDifferentValuesStr = numOfDifferentValues.astype(str)
	numOfDifferentValuesStr = np.column_stack((attributeNamesSelected, numOfDifferentValuesStr))
	return numOfDifferentValuesStr

def combineRowsToOne(dataToCombine, nbrOfWorkWeeks, salaryInHour, dividentsFromStocsk, capitalGains, capitalLosses):
	nbrOfRows, numberOfColumns = np.shape(dataToCombine)
	combinedRow = np.zeros(nbrOfRows).reshape((nbrOfRows,1))
	
	for i in range(nbrOfRows):
		combinedRow[i] = dataToCombine[i,nbrOfWorkWeeks]*7.5*5*dataToCombine[i,salaryInHour] + dataToCombine[i,dividentsFromStocsk] + dataToCombine[i,capitalGains] - dataToCombine[i,capitalLosses]

	return combinedRow